<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>let var const</title>
</head>
<body>
<script>
//    面向对象  万物皆对象(js Object(基类)) 原型原型链
//    {}

//    ES5
//    var a = 3;

    //ES6
//    let a = 3;
//    const b = 3;



//let const命令, 都是用来声明变量的 语法类似于 var
//let var const 区别
//1.是否存在变量提升？ var声明的变量存在变量提升 let const不存在
//2.是否存在暂时性死区？ var声明的变量不存在暂时性死区 let const存在
//3.是否允许重复声明变量？ var声明的变量可以重复声明  let const不能重复声明
//4.是否存在块级作用域？ var声明的变量不存在块级作用域 let const存在
//5.是否能修改声明的变量？ var let 可以修改 const声明的变量不可以修改并且必须赋初始值



//变量提升 (预解释/预解析) ==>在变量未定义之前可以使用 并且不报错 值为undefined

/*console.log("A=",a);//undefined

var a;
function f1(){

    console.log("f1_A=",b);//undefined

    var b;

}

console.log("A=",a);//null undefined

a=1;

console.log("A=",a);//*/

 /*console.log("A=",a);//Uncaught ReferenceError: Cannot access 'a' before initialization

 let a = 1;

 console.log("A=",a);//*/

/* //作用域链
console.log("A=",a);//undefined

 var a = 1;

 function f1(){

     console.log("f1_A=",a, b);//undefined

     var b;

 }

 console.log("A=",a);//*/



/*//暂时性死区
if(1){

}else{

}

let a = 1;*/


/*//是否允许重复声明变量
var c = 100;
var c = 20;
console.log("C = ",c);

let f = 100;
let f = 10; //Uncaught SyntaxError: Identifier 'f' has already been declared
console.log("F = ",f) */

//块级作用域

/*{
    var f = 1;
}
console.log("f = ",f);



{
    let e = 1;
}
console.log("e = ",e);//Uncaught ReferenceError: e is not defined*/

/*if(0){
//    var a = 1;
    let a = 1;
}else {
    console.log("a = ",a)//undefined
}*/




//是否能修改声明的变量 const声明的变量不能修改
// 代表值有  PI~3.1415926 baseUrl

var a;
a = 1;
a = 2;

let b;
b = 1;
b = 2;

//const声明的变量 必须要赋值 并且 不能修改
const PI = 3.1415926; //数字 Number(基本数据类型)
//PI = 3.1415927; //Uncaught TypeError: Assignment to constant variable.

//const PI; //Uncaught SyntaxError: Missing initializer in const declaration
//PI = 3.1415926;

const obj = { //对象 Object(引用数据类型)
    a: 1
};
console.log("-----1-------",obj);
obj.a = 2;
console.log("-----2-------",obj);

/*obj = {
    a: 2
}*/
/*
* const 如果存储的是一个对象,实际上是存储的一个内存地址
*   只要内存地址不变,只修改地址里的内容是可以的.
* */
















    //关键点在于 变量i是全局的,函数执行时输出的都是全局作用于下i的值
/*    var arr = [];

    for(var i=0;i<2;i++){
        arr[i] = function(){
            console.log(i);
        }
    }

//    i = 2;

/!*    arr = [
        function () {
            console.log(i)
        },
        function () {
            console.log(i)
        }
    ];*!/

    arr[0](); // 1 0 0 1 undefined 2
    arr[1](); // 1 1 2 2 undefined 2*/


//关键点 每次循环都会产生一个块级做用户, 每个块级作用域中的变量都是不同的,
//函数执行的时候输出的其实是自己上一级(循环时产生的块级作用域)作用域下的值
/*let arr = [];

for (let i = 0; i < 2; i++) {
    arr[i] = function () {
        console.log(i);
    }
}
arr[0](); //0
arr[1](); //1*/




</script>
</body>
</html>